package com.lifeverse.entity;

import com.lifeverse.entity.enums.ValueAssessmentStatus;
import com.lifeverse.entity.enums.ValueType;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 价值评估实体类
 * 记录对各种活动、决策、项目的价值评估
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "value_assessments", indexes = {
    @Index(name = "idx_value_assessment_title", columnList = "title"),
    @Index(name = "idx_value_assessment_type", columnList = "value_type"),
    @Index(name = "idx_value_assessment_status", columnList = "status"),
    @Index(name = "idx_value_assessment_assessor", columnList = "assessor_id"),
    @Index(name = "idx_value_assessment_target", columnList = "target_entity_id"),
    @Index(name = "idx_value_assessment_created", columnList = "assessment_date")
})
public class ValueAssessment extends BaseEntity {
    
    /**
     * 评估标题
     */
    @Column(name = "title", nullable = false, length = 200)
    private String title;
    
    /**
     * 评估描述
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;
    
    /**
     * 价值类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "value_type", nullable = false, length = 30)
    private ValueType valueType;
    
    /**
     * 评估状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 30)
    private ValueAssessmentStatus status = ValueAssessmentStatus.PENDING;
    
    /**
     * 评估者
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "assessor_id", nullable = false)
    private LifeEntity assessor;
    
    /**
     * 评估目标实体
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "target_entity_id")
    private LifeEntity targetEntity;
    
    /**
     * 关联决策
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "decision_id")
    private Decision decision;
    
    /**
     * 关联协作任务
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "collaboration_task_id")
    private CollaborationTask collaborationTask;
    
    /**
     * 评估日期
     */
    @Column(name = "assessment_date", nullable = false)
    private LocalDateTime assessmentDate;
    
    /**
     * 评估开始时间
     */
    @Column(name = "started_at")
    private LocalDateTime startedAt;
    
    /**
     * 评估完成时间
     */
    @Column(name = "completed_at")
    private LocalDateTime completedAt;
    
    /**
     * 评估截止时间
     */
    @Column(name = "deadline")
    private LocalDateTime deadline;
    
    /**
     * 评估方法
     */
    @Column(name = "assessment_method", length = 100)
    private String assessmentMethod;
    
    /**
     * 评估标准
     */
    @Column(name = "assessment_criteria", columnDefinition = "TEXT")
    private String assessmentCriteria;
    
    /**
     * 基准值
     */
    @Column(name = "baseline_value", precision = 15, scale = 4)
    private BigDecimal baselineValue;
    
    /**
     * 当前值
     */
    @Column(name = "current_value", precision = 15, scale = 4)
    private BigDecimal currentValue;
    
    /**
     * 目标值
     */
    @Column(name = "target_value", precision = 15, scale = 4)
    private BigDecimal targetValue;
    
    /**
     * 预期价值
     */
    @Column(name = "expected_value", precision = 15, scale = 4)
    private BigDecimal expectedValue;
    
    /**
     * 实际价值
     */
    @Column(name = "actual_value", precision = 15, scale = 4)
    private BigDecimal actualValue;
    
    /**
     * 价值单位
     */
    @Column(name = "value_unit", length = 50)
    private String valueUnit;
    
    /**
     * 置信度（0-100）
     */
    @Column(name = "confidence_level", precision = 5, scale = 2)
    private BigDecimal confidenceLevel;
    
    /**
     * 准确性评分（0-100）
     */
    @Column(name = "accuracy_score", precision = 5, scale = 2)
    private BigDecimal accuracyScore;
    
    /**
     * 影响范围
     */
    @Column(name = "impact_scope", length = 100)
    private String impactScope;
    
    /**
     * 时间范围（开始）
     */
    @Column(name = "time_range_start")
    private LocalDateTime timeRangeStart;
    
    /**
     * 时间范围（结束）
     */
    @Column(name = "time_range_end")
    private LocalDateTime timeRangeEnd;
    
    /**
     * 评估权重
     */
    @Column(name = "assessment_weight", precision = 5, scale = 4)
    private BigDecimal assessmentWeight = BigDecimal.ONE;
    
    /**
     * 风险调整因子
     */
    @Column(name = "risk_adjustment_factor", precision = 5, scale = 4)
    private BigDecimal riskAdjustmentFactor = BigDecimal.ONE;
    
    /**
     * 数据来源
     */
    @Column(name = "data_sources", columnDefinition = "TEXT")
    private String dataSources;
    
    /**
     * 评估假设
     */
    @Column(name = "assumptions", columnDefinition = "TEXT")
    private String assumptions;
    
    /**
     * 限制条件
     */
    @Column(name = "limitations", columnDefinition = "TEXT")
    private String limitations;
    
    /**
     * 评估结论
     */
    @Column(name = "conclusion", columnDefinition = "TEXT")
    private String conclusion;
    
    /**
     * 建议措施
     */
    @Column(name = "recommendations", columnDefinition = "TEXT")
    private String recommendations;
    
    /**
     * 评估标签（JSON格式）
     */
    @Column(name = "tags", length = 500)
    private String tags;
    
    /**
     * 评估属性（JSON格式）
     */
    @Column(name = "attributes", columnDefinition = "TEXT")
    private String attributes;
    
    /**
     * 评估数据（JSON格式）
     */
    @Column(name = "assessment_data", columnDefinition = "TEXT")
    private String assessmentData;
    
    /**
     * 计算模型（JSON格式）
     */
    @Column(name = "calculation_model", columnDefinition = "TEXT")
    private String calculationModel;
    
    /**
     * 验证结果（JSON格式）
     */
    @Column(name = "validation_results", columnDefinition = "TEXT")
    private String validationResults;
    
    /**
     * 价值分解记录
     */
    @OneToMany(mappedBy = "valueAssessment", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<ValueBreakdown> valueBreakdowns = new ArrayList<>();
    
    /**
     * 价值趋势记录
     */
    @OneToMany(mappedBy = "valueAssessment", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<ValueTrend> valueTrends = new ArrayList<>();
    
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (assessmentDate == null) {
            assessmentDate = LocalDateTime.now();
        }
    }
    
    /**
     * 开始评估
     */
    public void startAssessment() {
        if (this.status.canStartAssessment()) {
            this.status = ValueAssessmentStatus.IN_PROGRESS;
            this.startedAt = LocalDateTime.now();
        }
    }
    
    /**
     * 完成评估
     */
    public void completeAssessment(BigDecimal actualValue, String conclusion) {
        this.status = ValueAssessmentStatus.COMPLETED;
        this.completedAt = LocalDateTime.now();
        this.actualValue = actualValue;
        this.conclusion = conclusion;
        
        // 计算准确性评分
        if (expectedValue != null && actualValue != null) {
            this.accuracyScore = calculateAccuracyScore();
        }
    }
    
    /**
     * 批准评估
     */
    public void approve(String approverComments) {
        if (this.status == ValueAssessmentStatus.COMPLETED || this.status == ValueAssessmentStatus.NEEDS_REVIEW) {
            this.status = ValueAssessmentStatus.APPROVED;
            this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + 
                         "批准意见: " + approverComments);
        }
    }
    
    /**
     * 拒绝评估
     */
    public void reject(String rejectionReason) {
        this.status = ValueAssessmentStatus.REJECTED;
        this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + 
                     "拒绝原因: " + rejectionReason);
    }
    
    /**
     * 取消评估
     */
    public void cancel(String reason) {
        if (this.status.canCancel()) {
            this.status = ValueAssessmentStatus.CANCELLED;
            this.completedAt = LocalDateTime.now();
            this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + 
                         "取消原因: " + reason);
        }
    }
    
    /**
     * 标记需要复审
     */
    public void markForReview(String reason) {
        this.status = ValueAssessmentStatus.NEEDS_REVIEW;
        this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + 
                     "复审原因: " + reason);
    }
    
    /**
     * 更新当前值
     */
    public void updateCurrentValue(BigDecimal newValue) {
        this.currentValue = newValue;
        
        // 如果有目标值，检查是否达到目标
        if (targetValue != null && newValue.compareTo(targetValue) >= 0) {
            this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + 
                         "已达到目标值: " + targetValue);
        }
    }
    
    /**
     * 计算价值增长
     */
    public BigDecimal calculateValueGrowth() {
        if (baselineValue == null || currentValue == null || baselineValue.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        return currentValue.subtract(baselineValue)
                .divide(baselineValue, 4, java.math.RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
    }
    
    /**
     * 计算目标达成率
     */
    public BigDecimal calculateTargetAchievementRate() {
        if (targetValue == null || baselineValue == null || currentValue == null) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal targetGrowth = targetValue.subtract(baselineValue);
        BigDecimal actualGrowth = currentValue.subtract(baselineValue);
        
        if (targetGrowth.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.valueOf(100);
        }
        
        return actualGrowth.divide(targetGrowth, 4, java.math.RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100))
                .max(BigDecimal.ZERO);
    }
    
    /**
     * 计算准确性评分
     */
    private BigDecimal calculateAccuracyScore() {
        if (expectedValue == null || actualValue == null || expectedValue.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        BigDecimal difference = expectedValue.subtract(actualValue).abs();
        BigDecimal errorRate = difference.divide(expectedValue, 4, java.math.RoundingMode.HALF_UP);
        
        return BigDecimal.valueOf(100).subtract(errorRate.multiply(BigDecimal.valueOf(100)))
                .max(BigDecimal.ZERO);
    }
    
    /**
     * 计算风险调整后价值
     */
    public BigDecimal calculateRiskAdjustedValue() {
        if (currentValue == null || riskAdjustmentFactor == null) {
            return currentValue;
        }
        
        return currentValue.multiply(riskAdjustmentFactor);
    }
    
    /**
     * 计算加权价值
     */
    public BigDecimal calculateWeightedValue() {
        if (currentValue == null || assessmentWeight == null) {
            return currentValue;
        }
        
        return currentValue.multiply(assessmentWeight);
    }
    
    /**
     * 判断是否超时
     */
    public boolean isOverdue() {
        return deadline != null && LocalDateTime.now().isAfter(deadline) && !status.isCompleted();
    }
    
    /**
     * 判断是否达到目标
     */
    public boolean hasReachedTarget() {
        return targetValue != null && currentValue != null && currentValue.compareTo(targetValue) >= 0;
    }
    
    /**
     * 计算评估持续时间（分钟）
     */
    public long getAssessmentDurationMinutes() {
        if (startedAt == null) {
            return 0;
        }
        
        LocalDateTime endTime = completedAt != null ? completedAt : LocalDateTime.now();
        return java.time.Duration.between(startedAt, endTime).toMinutes();
    }
    
    /**
     * 计算价值变化率
     */
    public BigDecimal calculateValueChangeRate() {
        if (expectedValue == null || actualValue == null || expectedValue.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        return actualValue.subtract(expectedValue)
                .divide(expectedValue, 4, java.math.RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100));
    }
    
    /**
     * 判断是否为高价值评估
     */
    public boolean isHighValue() {
        if (currentValue == null) {
            return false;
        }
        
        // 根据价值类型定义高价值阈值
        BigDecimal threshold = getHighValueThreshold();
        return currentValue.compareTo(threshold) >= 0;
    }
    
    /**
     * 获取高价值阈值
     */
    private BigDecimal getHighValueThreshold() {
        switch (valueType) {
            case ECONOMIC:
                return BigDecimal.valueOf(100000); // 10万经济价值
            case SOCIAL:
            case ENVIRONMENTAL:
                return BigDecimal.valueOf(80); // 80分社会/环境价值
            case TECHNOLOGICAL:
            case INNOVATION:
                return BigDecimal.valueOf(85); // 85分技术/创新价值
            default:
                return BigDecimal.valueOf(75); // 75分其他价值
        }
    }
}